// Package zlib provides ...
package zlib

import (
	"strings"
	"time"

	"github.com/spf13/viper"
)

type Config struct {
	configList map[string]*viper.Viper
}

// 加载配置，默认文件是app.toml
// 如果配置文件是app.toml,配置项是key,则可以直接获取key值
// 如果配置文件是other.toml,配置项是key，则通过other.key获取配置项
// 配置项一般加引号
func NewConfig(configPath string, ext string) Config {
	var configList map[string]*viper.Viper
	configList = make(map[string]*viper.Viper)
	fileList, err := Glob(configPath+"/*."+ext, true)
	if err != nil || len(fileList) == 0 {
		panic("error config files")
	}
	for _, v := range fileList {
		config := viper.New()
		config.AddConfigPath(configPath)
		// 支持多个配置文件,指定目录
		config.SetConfigFile(configPath + "/" + v)
		config.SetConfigType("toml")
		config.ReadInConfig()
		configList[strings.TrimRight(Basename(v), Ext(v))] = config
	}

	config := &Config{}
	config.configList = configList
	return *config
}

func (c *Config) getViper(keyname string) *viper.Viper {
	fileName := strings.Split(keyname, ".")[0]
	viper := c.configList[fileName]
	return viper
}

func (c *Config) getOriginKey(keyname string) (fileName string, realKeyName string) {
	fileName = strings.Split(keyname, ".")[0]
	if _, ok := c.configList[fileName]; !ok {
		fileName = "app"
		realKeyName = keyname
	} else {
		realKeyName = strings.TrimLeft(keyname, fileName)
		realKeyName = strings.Trim(realKeyName, ".")
	}

	return
}

// get 一个原始值
func (c *Config) Get(keyname string) interface{} {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).Get(realKeyName)
}

// getstring
func (c *Config) GetString(keyname string) string {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetString(realKeyName)
}

func (c *Config) GetStringByDefault(keyname string, value string) string {
	fileName, realKeyName := c.getOriginKey(keyname)
	configValue := c.getViper(fileName).GetString(realKeyName)
	if configValue == "" {
		configValue = value
	}
	return configValue
}

// getbool
func (c *Config) GetBool(keyname string) bool {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetBool(realKeyName)
}

// getint
func (c *Config) GetInt(keyname string) int {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetInt(realKeyName)
}

func (c *Config) GetIntByDefault(keyname string, value int) int {
	fileName, realKeyName := c.getOriginKey(keyname)
	configValue := c.getViper(fileName).GetInt(realKeyName)
	if configValue == 0 {
		configValue = value
	}
	return configValue
}

// getint32
func (c *Config) GetInt32(keyname string) int32 {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetInt32(realKeyName)
}

func (c *Config) GetInt32ByDefault(keyname string, value int32) int32 {
	fileName, realKeyName := c.getOriginKey(keyname)
	configValue := c.getViper(fileName).GetInt32(realKeyName)
	if configValue == 0 {
		configValue = value
	}
	return configValue
}

// getint64
func (c *Config) GetInt64(keyname string) int64 {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetInt64(realKeyName)
}
func (c *Config) GetInt64ByDefault(keyname string, value int64) int64 {
	fileName, realKeyName := c.getOriginKey(keyname)
	configValue := c.getViper(fileName).GetInt64(realKeyName)
	if configValue == 0 {
		configValue = value
	}
	return configValue
}

// float64
func (c *Config) GetFloat64(keyname string) float64 {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetFloat64(realKeyName)
}

func (c *Config) GetFloat64ByDefault(keyname string, value float64) float64 {
	fileName, realKeyName := c.getOriginKey(keyname)
	configValue := c.getViper(fileName).GetFloat64(realKeyName)
	if configValue == 0 {
		configValue = value
	}
	return configValue
}

// GetDuration
func (c *Config) GetDuration(keyname string) time.Duration {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetDuration(realKeyName)
}

// GetStringSlice
func (c *Config) GetStringSlice(keyname string) []string {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetStringSlice(realKeyName)
}

// GetStringMap
func (c *Config) GetStringMap(keyname string) map[string]interface{} {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetStringMap(realKeyName)
}

// GetStringMapString
func (c *Config) GetStringMapString(keyname string) map[string]string {
	fileName, realKeyName := c.getOriginKey(keyname)
	return c.getViper(fileName).GetStringMapString(realKeyName)
}
